package ca.inrs.ete.app.shopx;
import java.lang.ref.WeakReference;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import ca.inrs.ete.app.shopx.util.Constants;

public class SHOPFoldersViewAdapter extends BaseAdapter implements OnItemClickListener, 
																   OnItemLongClickListener,
																   ActionMode.Callback {
	public enum VIEW_MODE {VIEW_MODE_GRID, VIEW_MODE_PAGER};

	public static class ListItem {
		public Uri     uri;
		public String  name;
		public boolean isSelected;
	}

	private static class ViewHolder {
		CheckBox mCheck;
		TextView mText;
	}

	private Activity       mActivity  = null;
	private LayoutInflater mInflater  = null;
	private ActionMode     mActionMode= null;
	private ListItem[]     mItems     = null;
	private ViewGroup      mParent    = null;
	private WeakReference<CheckBox>  mClicked = null;

	public SHOPFoldersViewAdapter(Activity c) {
		mActivity = c;
		mInflater = LayoutInflater.from(c);
	}

	public void setItems(ListItem[] items) {
		mItems =  items;
	}

	public int getCount() {
		return (mItems == null) ? 0 : mItems.length;
	}

	public Object getItem(int position) {
		return mItems[position];
	}

	public long getItemId(int position) {
		return mItems[position].hashCode();
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		mParent = parent;

		ViewHolder holder = null;
		if (convertView == null) {
			convertView = mInflater.inflate(R.layout.activity_view_dir_item, null);

			holder = new ViewHolder();
			holder.mCheck = (CheckBox) convertView.findViewById(R.id.folder_item_checkBox);
			holder.mText  = (TextView) convertView.findViewById(R.id.folder_item_textView);
			convertView.setTag(holder);
		} 
		else {
			holder = (ViewHolder) convertView.getTag();
		}

		ListItem item = mItems[position];
		holder.mText.setText(item.name);
		holder.mCheck.setChecked(item.isSelected);
		holder.mCheck.setTag(item);

		return convertView;
	}

	public void getSelection() {
		StringBuffer responseText = new StringBuffer();

		for (int i=0; i < mItems.length; ++i){
			ListItem item = mItems[i];
			if(item.isSelected) {
				responseText.append("\n" + item.name);
			}
		}

		Toast.makeText(mActivity, responseText, Toast.LENGTH_LONG).show();
	}

	public boolean isItemSelected() {
		for (ListItem item : mItems) {
			if (item.isSelected) return true;
		}
		return false;
	}

	public void OnCheckboxClick(View view) {

		// ---  Exclusive behavior
		if (mClicked != null) {
			CheckBox cb = mClicked.get();
			if (cb != null) {
				ListItem item = (ListItem) cb.getTag();
				item.isSelected = false;
				mClicked.get().setChecked(false);
			}
			mClicked = null;
		}

		// ---  Get new state
		CheckBox cb = (CheckBox) view;
		ListItem item = (ListItem) cb.getTag();
		item.isSelected = cb.isChecked();

		// ---  Exclusive behavior
		if (item.isSelected) {
			mClicked = new WeakReference<CheckBox>(cb);			
		}

		// ---  Set action mode depending on global state 
		if (isItemSelected()) {
			if (mActionMode == null) mActionMode = mActivity.startActionMode(this);
		}
		else { 
			if (mActionMode != null) mActionMode.finish();
			mActionMode = null;
		}
	}

	public void unselectAll() {
		for (ListItem item : mItems) {
			item.isSelected = false;
		}
	}


	/**
	 * ************************************************************************
	 * implements AdapterView.OnItemClickListener
	 * ************************************************************************
	 */
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		final SHOPPreferences prefs = new SHOPPreferences();
		prefs.readValues( PreferenceManager.getDefaultSharedPreferences(mActivity) );

		switch (prefs.getFilesMode()) {
		case VIEW_MODE_GRID: {
			SHOPFoldersViewAdapter.ListItem item = (ListItem) getItem(position);
			Intent viewIntent = new Intent(Intent.ACTION_VIEW, item.uri);
			viewIntent.addCategory(mActivity.getString(R.string.app_intent_category_files_grid));
			mActivity.startActivity(viewIntent);
			break;
		}
		case VIEW_MODE_PAGER: {
			SHOPFoldersViewAdapter.ListItem item = (ListItem) getItem(position);
			Intent viewIntent = new Intent(Intent.ACTION_VIEW, item.uri);
			viewIntent.addCategory(mActivity.getString(R.string.app_intent_category_files_pager));
			viewIntent.putExtra(Constants.INTENT_EXTRA_INT, 0);
			mActivity.startActivity(viewIntent);
			break;
		}
		default: break;
		}
	}


	/**
	 * ************************************************************************
	 * implements AdapterView.OnItemLongClickListener
	 * ************************************************************************
	 */
	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
		if (mActionMode != null) {
			return false;
		}

		mActionMode = mActivity.startActionMode(this);
		view.setSelected(true);
		return true;
	}

	/**
	 * ************************************************************************
	 * implements ActionMode.Callback
	 * ************************************************************************
	 */
	@Override
	public boolean onCreateActionMode(ActionMode mode, Menu menu) {
		MenuInflater inflater = mode.getMenuInflater();
		inflater.inflate(R.menu.activity_view_folders, menu);
		return true;
	}

	// Called each time the action mode is shown. Always called after onCreateActionMode, but
	// may be called multiple times if the mode is invalidated.
	@Override
	public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
		return false;
	}

	// Called when the user selects a contextual menu item
	@Override
	public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_archive: onMenuArchive(); mode.finish(); return true;
		case R.id.menu_delete:  onMenuDelete (); mode.finish(); return true;
		default:
			return false;
		}
	}

	// Called when the user exits the action mode
	@Override
	public void onDestroyActionMode(ActionMode mode) {
		mActionMode = null;
	}

	/**
	 * ************************************************************************
	 * private method
	 * ************************************************************************
	 */
	private void onMenuArchive() {
		getSelection();
		Toast.makeText(mActivity, "TODO: Archive folder", Toast.LENGTH_LONG).show();
		resetSelection();
	}

	private void onMenuDelete() {
		getSelection();
		Toast.makeText(mActivity, "TODO: Delete folder", Toast.LENGTH_LONG).show();
		resetSelection();
	}

	private void resetSelection() {
		unselectAll();
		if (mParent != null) mParent.invalidate();
	}

}

